package com.df.gamesynctest.handler;

import com.alibaba.fastjson2.JSON;
import com.df.gamesynctest.entity.GameMap;
import com.df.gamesynctest.entity.Player;
import com.df.gamesynctest.entity.UserManager;
import com.df.gamesynctest.msg.MsgWrapper;
import com.df.gamesynctest.msg.S2C_SyncId;
import com.df.gamesynctest.net.MsgManager;
import com.df.gamesynctest.net.Server;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.Attribute;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;

@ChannelHandler.Sharable
@Slf4j
public class MsgCodecs extends MessageToMessageCodec<ByteBuf, MsgWrapper> {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        //正常流程是连接后给15秒的空余时间登录，未登录则断开连接
        Player player = new Player();
        player.id = Server.id.getAndIncrement();
        player.channel = ctx.channel();
        UserManager.getInstance().id2player.put(player.id,player);
        Attribute<Integer> attr = ctx.channel().attr(Server.idKey);
        attr.set(player.id);
        S2C_SyncId s2CSyncId = new S2C_SyncId();
        s2CSyncId.playerId= player.id;

        ctx.channel().writeAndFlush(MsgWrapper.createMsgWrapper(s2CSyncId));
        System.out.println("有新连接加入！");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        Attribute<Integer> attr = ctx.channel().attr(Server.idKey);
        UserManager.getInstance().id2player.remove(attr.get());
        Iterator<Player> iterator = GameMap.getInstance().players.iterator();
        while (iterator.hasNext()){
            Player next = iterator.next();
            if(next.id==attr.get()){
                iterator.remove();
                break;
            }
        }
        System.out.println("有连接断开:"+attr.get()+" 地图剩余玩家数量："+UserManager.getInstance().id2player.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("有连接异常！");
        super.exceptionCaught(ctx,cause);
    }

    @Override
    protected void encode(ChannelHandlerContext ctx, MsgWrapper msg, List<Object> out) throws Exception {
        int id = msg.id;
        System.out.println("编码消息："+id);
        out.add(msg.toByteBuff());
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        // 解码逻辑
        if (msg.readableBytes() < 4)
        {
            System.out.println("消息成都不够");
            return;
        }

        msg.markReaderIndex();
        int len = msg.readInt();
        if (msg.readableBytes() < len - 4)
        {
            System.out.println("消息内容长度不够");
            msg.resetReaderIndex();
            return;
        }

        int msgId = msg.readInt();
        Class msgType = MsgManager.getInstance().msgId2Type.get(msgId);
        if (msgType==null)
        {
            System.out.println("未根据消息id找到消息类型");
            msg.readerIndex(msg.readerIndex() + len - 8);
            return;
        }

        ByteBuf byteBuffer = msg.readBytes(len-8);
        String content =  byteBuffer.toString(StandardCharsets.UTF_8);

        Object msgObj = JSON.parseObject(content, msgType);
        log.info("消息类型："+msgType.getName()+"  消息内容："+content);
        Attribute<Integer> attr = ctx.channel().attr(Server.idKey);
        Integer playerId = attr.get();
        MsgWrapper msgWrapper = MsgWrapper.createMsgWrapper(msgObj);
        msgWrapper.playerId = playerId;
        try
        {
            MsgDispatcher.getInstance().distapcherMsg(msgWrapper);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
